#include "stdc/stdc++.h"
/**
 * 处理器接口声明了一个用于构建处理器链的方法。
 * 它还声明了一个用于执行请求的方法。
 */
class Handler
{
   public:
    virtual Handler *SetNext(Handler *handler) = 0;
    virtual std::string Handle(std::string request) = 0;
};

/**
 * 默认的链式行为可以在基础处理器类中实现。
 */
class AbstractHandler : public Handler
{
   private:
    Handler *next_handler_;

   public:
    AbstractHandler() : next_handler_(nullptr) {}
    Handler *SetNext(Handler *handler) override
    {
        this->next_handler_ = handler;
        // 从这里返回一个处理器将使我们能够以一种方便的方式链接处理器，如下所示：
        // $monkey->setNext($squirrel)->setNext($dog);
        return handler;
    }
    std::string Handle(std::string request) override
    {
        if (this->next_handler_)
        {
            return this->next_handler_->Handle(request);
        }

        return {};
    }
};

/**
 * 所有具体处理器都要么处理请求，要么将其传递给链中的下一个处理器。
 */
class MonkeyHandler : public AbstractHandler
{
   public:
    std::string Handle(std::string request) override
    {
        if (request == "Banana")
        {
            return "Monkey: I'll eat the " + request + ".\n";
        }
        else
        {
            return AbstractHandler::Handle(request);
        }
    }
};

class SquirrelHandler : public AbstractHandler
{
   public:
    std::string Handle(std::string request) override
    {
        if (request == "Nut")
        {
            return "Squirrel: I'll eat the " + request + ".\n";
        }
        else
        {
            return AbstractHandler::Handle(request);
        }
    }
};

class DogHandler : public AbstractHandler
{
   public:
    std::string Handle(std::string request) override
    {
        if (request == "MeatBall")
        {
            return "Dog: I'll eat the " + request + ".\n";
        }
        else
        {
            return AbstractHandler::Handle(request);
        }
    }
};

/**
 * 客户端代码通常适用于与单个处理器一起工作。在大多数情况下，它甚至不知道
 * 处理器是链的一部分。
 */
void ClientCode(Handler &handler)
{
    std::vector<std::string> food = {"Nut", "Banana", "Cup of coffee"};
    for (const std::string &f : food)
    {
        std::cout << "Client: Who wants a " << f << "?\n";
        const std::string result = handler.Handle(f);
        if (!result.empty())
        {
            std::cout << "  " << result;
        }
        else
        {
            std::cout << "  " << f << " was left untouched.\n";
        }
    }
}

/**
 * 客户端代码的另一部分构建实际的链。
 */
int main()
{
    MonkeyHandler *monkey = new MonkeyHandler;
    SquirrelHandler *squirrel = new SquirrelHandler;
    DogHandler *dog = new DogHandler;
    monkey->SetNext(squirrel)->SetNext(dog);

    /**
     * 客户端应该能够向任何处理器发送请求，而不仅仅是链中的第一个处理器。
     */
    std::cout << "链: 猴子 > 松鼠 > 狗\n\n";
    ClientCode(*monkey);
    std::cout << "\n";
    std::cout << "子链: 松鼠 > 狗\n\n";
    ClientCode(*squirrel);

    delete monkey;
    delete squirrel;
    delete dog;

    return 0;
}